import sys
import numpy as np
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget
from PyQt5.QtGui import QPixmap, QImage
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib.backends.backend_agg import FigureCanvasAgg

class AnimatedBubbleSortCanvas(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.label = QLabel(self)
        layout = QVBoxLayout()
        layout.addWidget(self.label)
        self.setLayout(layout)

        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.ax = self.fig.add_subplot(111)
        self.data = np.random.randint(0, 100, 10)
        self.rects = self.ax.bar(range(len(self.data)), self.data, align='center')
        self.ax.set_ylim(0, 110)

        self.steps = self.bubble_sort_steps(self.data.copy())

        # Initialize the animation and keep a reference to it
        self.anim = animation.FuncAnimation(self.fig, self.update, frames=len(self.steps), interval=500, repeat=False)
        self.draw_initial()

    def bubble_sort_steps(self, data):
        steps = []
        n = len(data)
        for i in range(n):
            for j in range(0, n - i - 1):
                if data[j] > data[j + 1]:
                    data[j], data[j + 1] = data[j + 1], data[j]
                steps.append(data.copy())
        return steps

    def update(self, frame):
        current_data = self.steps[frame]
        for rect, h in zip(self.rects, current_data):
            rect.set_height(h)
        self.draw()

    def draw_initial(self):
        canvas = FigureCanvasAgg(self.fig)
        canvas.draw()
        buf = canvas.buffer_rgba()
        w, h = canvas.get_width_height()
        image = QImage(buf, w, h, QImage.Format_ARGB32)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)
        self.label.update()

    def draw(self):
        canvas = FigureCanvasAgg(self.fig)
        canvas.draw()
        buf = canvas.buffer_rgba()
        w, h = canvas.get_width_height()
        image = QImage(buf, w, h, QImage.Format_ARGB32)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)
        self.label.update()

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Bubble Sort Animation in QLabel")
        self.canvas = AnimatedBubbleSortCanvas(self)
        self.setCentralWidget(self.canvas)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())
